/********************************************************************
	created:	2010/07/13
	created:	13:7:2010   10:08
	filename: 	D:\Proj\gcstock\code\C++\Base\GCAllocator.h
	file path:	D:\Proj\gcstock\code\C++\Base
	file base:	GCAllocator
	file ext:	h
	author:		Greg Song
	
	purpose:	
*********************************************************************/

#ifndef _GC_ALLOCATOR_H_
#define _GC_ALLOCATOR_H_
#include "GCHeader.h"
#include <new>

namespace gcstock
{
    template<typename T> class GCBaseAllocator
    {
    public:
        typedef size_t      size_type;
        typedef ptrdiff_t   difference_type;
        typedef T*          pointer;
        typedef const T*    const_pointer;
        typedef T&          reference;
        typedef const T&    const_reference;
        typedef T           value_type;
        
        GCBaseAllocator() throw() {}
        ~GCBaseAllocator()throw(){}

        template<typename T1>
            GCBaseAllocator(const GCBaseAllocator<T1>&)throw(){}      
        GCBaseAllocator(const GCBaseAllocator&) throw(){}


       
        
        pointer
            address(reference __x) const { return &__x; }
        
        const_pointer
            address(const_reference __x) const { return &__x; }
        
        // NB: __n is permitted to be 0.  The C++ standard says nothing
        // about what the return value is when __n == 0.
        pointer
            allocate(size_type __n, const void* = 0)
        { 
            return static_cast<T*>(::operator new(__n * sizeof(T))); 
        }
        
        // __p is not permitted to be a null pointer.
        void
            deallocate(pointer __p, size_type)
        { ::operator delete(__p); }
        
        // size_t(-1) == 0xFFFFFFFF (32bits OS)
        size_type
            max_size() const throw() 
        { return size_t(-1) / sizeof(T); }
        
        // call placement new to initialize the memory. notice that there is no memory   
        // allocating in this function
        void 
            construct(pointer __p, const T& __val) 
        { ::new(__p) T(__val); }
        
        // No memory release
        void 
            destroy(pointer __p) { __p->~T(); }
    };
    
    template<typename T>
        inline bool
        operator==(const GCBaseAllocator<T>&, const GCBaseAllocator<T>&)
    { return true; }
    
    template<typename T>
        inline bool
        operator!=(const GCBaseAllocator<T>&, const GCBaseAllocator<T>&)
    { return false; }
}

#endif // _GC_ALLOCATOR_H_